// Copyright 2009 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Author: Jeff Stewart
// Inspects configurations from Outlook Express 6,
// Outlook 2000, Outlook 2003, Outlook 2007,
// and Windows Mail.

#ifndef POPDIAG_CONFIG_OUTLOOK_H__
#define POPDIAG_CONFIG_OUTLOOK_H__

#include "config/configverifier.h"
#include "config/registrykey.h"
#include "util/common.h"

namespace popdiag {

class Protocol;

typedef enum {
  ACCOUNT_NAME,
  REG_POP3_LEAVE_ON_SERVER,
  REG_POP3_PORT,
  REG_POP3_SERVER,
  REG_POP3_SKIP_ACCOUNT,
  REG_POP3_TIMEOUT,
  REG_POP3_USE_SPA,
  REG_POP3_USE_SSL,
  REG_POP3_USERNAME,
  REG_IMAP_PORT,
  REG_IMAP_SERVER,
  REG_IMAP_USE_SSL,
  REG_IMAP_USE_SPA,
  REG_IMAP_USERNAME,
  REG_IMAP_FOLDER_PATH,
  REG_SMTP_AUTH_METHOD,
  REG_SMTP_AUTH_USERNAME,
  REG_SMTP_DISPLAY_NAME,
  REG_SMTP_EMAIL_ADDRESS,
  REG_SMTP_PORT,
  REG_SMTP_SERVER,
  REG_SMTP_SPLIT_MESSAGES,
  REG_SMTP_SSL_VARIANT,
  REG_SMTP_TIMEOUT,
  REG_SMTP_USE_AUTH,
  REG_SMTP_USE_SPA,
  REG_SMTP_USE_SSL,
} RegistryEntryId;

 typedef enum {
   OUTLOOK_EXPRESS_6,
   WINDOWS_MAIL,
   WINDOWS_LIVE_MAIL,
   OUTLOOK_2000,
   OUTLOOK_2002,
   OUTLOOK_2003,
   OUTLOOK_2007,
 } OutlookVersion;

// Get the key where the given version of outlook stores a configuration value.
const char *GetRegistryKeyName(RegistryEntryId id, OutlookVersion v);

class Outlook : public ConfigVerifier {
  Q_OBJECT;
 public:
  Outlook(OutlookVersion version);
  virtual ~Outlook();

  virtual bool CheckConfiguration(VerificationSet *out) const;
  virtual QString program_name() const;
  virtual QString program_code() const;

  // Returns the path where the binary will be installed, if present.
  QString GetBinaryPath() const;

 private:
  typedef scoped_ptr<RegistryKey> KeyHolder;

  RegistryKey *GetProfileContainer() const;
  bool GetInterestingProfiles(QList<RegistryKey *> *out) const;
  bool GetInterestingProfilesFromDisk(QList<RegistryKey *> *out) const;
  bool GetInterestingProfilesFromRegistry(QList<RegistryKey *> *out) const;

  const OutlookVersion version_;
};

class ProtocolRegistryKeys;
class ReceiveProtocolRegistryKeys;
class ProtocolFaults;
class ReceiveProtocolFaults;

class OutlookProfileInspection : public VerificationResult {
  Q_OBJECT
 public:
  explicit OutlookProfileInspection(const RegistryKey &root,
                                    OutlookVersion version);

  void Recalculate(const QString &email);

 private:
  bool ReadConfig(RegistryEntryId item, QString *out) const;
  bool ReadConfig(RegistryEntryId item, int *out) const;
  QString program_name_in_english() const;

  void ValidateServerAndPort(const Protocol& protocol,
                             const ProtocolRegistryKeys& registry_keys,
                             const ProtocolFaults& faults,
                             QString *serverptr,
                             int *portptr,
                             bool validate_port);
  void ValidateAuth(const Protocol& protocol,
                    const ReceiveProtocolRegistryKeys& registry_keys,
                    const ReceiveProtocolFaults& faults);

  bool HasServer(const RegistryEntryId&) const;

  bool HasPop() const;
  void ValidatePop();
  void ValidatePopMisc();

  bool HasImap() const;
  void ValidateImap();
  void ValidateImapMisc();

  void ValidateSmtp();
  void ValidateSmtpAuth();
  void ValidateSmtpAuthOutlookExpress();
  void ValidateSmtpAuthOutlook();
  void ValidateSmtpMisc();
  void ValidateSmtpOutlook2007Ssl();

  void NoteVersion();

  scoped_ptr<RegistryKey> root_;
  QString  email_;
  const OutlookVersion version_;
};

}  // namespace popdiag

#endif  // POPDIAG_CONFIG_OUTLOOK_H__
